home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 25 / Cream of the Crop 25.iso / doom / quake_ad.zip / HIPQW.ZIP / SRC / COMBAT.QC < prev    next >
Text File  |  1997-03-13  |  7KB  |  351 lines

  1.  
  2. void() T_MissileTouch;
  3. void() info_player_start;
  4. void(entity targ, entity attacker) ClientObituary;
  5.  
  6. /*SERVER
  7. void() monster_death_use;
  8. */
  9.  
  10. //============================================================================
  11.  
  12. /*
  13. ============
  14. CanDamage
  15.  
  16. Returns true if the inflictor can directly damage the target.  Used for
  17. explosions and melee attacks.
  18. ============
  19. */
  20. float(entity targ, entity inflictor) CanDamage =
  21. {
  22. // bmodels need special checking because their origin is 0,0,0
  23.     if (targ.movetype == MOVETYPE_PUSH)
  24.     {
  25.         traceline(inflictor.origin, 0.5 * (targ.absmin + targ.absmax), TRUE, self);
  26.         if (trace_fraction == 1)
  27.             return TRUE;
  28.         if (trace_ent == targ)
  29.             return TRUE;
  30.         return FALSE;
  31.     }
  32.     
  33.     traceline(inflictor.origin, targ.origin, TRUE, self);
  34.     if (trace_fraction == 1)
  35.         return TRUE;
  36.     traceline(inflictor.origin, targ.origin + '15 15 0', TRUE, self);
  37.     if (trace_fraction == 1)
  38.         return TRUE;
  39.     traceline(inflictor.origin, targ.origin + '-15 -15 0', TRUE, self);
  40.     if (trace_fraction == 1)
  41.         return TRUE;
  42.     traceline(inflictor.origin, targ.origin + '-15 15 0', TRUE, self);
  43.     if (trace_fraction == 1)
  44.         return TRUE;
  45.     traceline(inflictor.origin, targ.origin + '15 -15 0', TRUE, self);
  46.     if (trace_fraction == 1)
  47.         return TRUE;
  48.  
  49.     return FALSE;
  50. };
  51.  
  52.  
  53. /*
  54. ============
  55. Killed
  56. ============
  57. */
  58. void(entity targ, entity attacker) Killed =
  59. {
  60.     local entity oself;
  61.  
  62.     oself = self;
  63.     self = targ;
  64.     
  65.     if (self.health < -99)
  66.         self.health = -99;        // don't let sbar look bad if a player
  67. //hip
  68. //MED
  69.    if (self.charmed)
  70.       {
  71.       self.effects = self.effects - (self.effects & EF_DIMLIGHT);
  72.       }
  73. //hip
  74.     if (self.movetype == MOVETYPE_PUSH || self.movetype == MOVETYPE_NONE)
  75.     {    // doors, triggers, etc
  76.         self.th_die ();
  77.         self = oself;
  78.         return;
  79.     }
  80.  
  81.     self.enemy = attacker;
  82.  
  83. // bump the monster counter
  84.     if (self.flags & FL_MONSTER)
  85.     {
  86.         killed_monsters = killed_monsters + 1;
  87.         WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
  88.     }
  89.  
  90.     ClientObituary(self, attacker);
  91.     
  92.     self.takedamage = DAMAGE_NO;
  93.     self.touch = SUB_Null;
  94.     self.effects = 0;
  95.  
  96. /*SERVER
  97.     monster_death_use();
  98. */
  99.     self.th_die ();
  100.     
  101.     self = oself;
  102. };
  103.  
  104.  
  105. /*
  106. ============
  107. T_Damage
  108.  
  109. The damage is coming from inflictor, but get mad at attacker
  110. This should be the only function that ever reduces health.
  111. ============
  112. */
  113. //hip
  114. //MED 01/10/97 added empathyused variable
  115. float empathyused;
  116. //hip
  117.  
  118. void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
  119. {
  120.     local    vector    dir;
  121.     local    entity    oldself;
  122.     local    float    save;
  123.     local    float    take;
  124.     local    string    s;
  125.     local    float    attackerteam, targteam;
  126.  
  127.  
  128.     if (!targ.takedamage)
  129.         return;
  130.  
  131. //hip
  132.  if (discharged && targ.wetsuit_finished )
  133.       return;
  134. //hip
  135.  
  136. // used by buttons and triggers to set activator for target firing
  137.     damage_attacker = attacker;
  138.  
  139. // check for quad damage powerup on the attacker
  140.     if (attacker.super_damage_finished > time)
  141.         damage = damage * 4;
  142.  
  143. //hip
  144. //MED
  145. //check for empathy shields
  146.    if ((targ.items2 & HIP_IT_EMPATHY_SHIELDS) && !(inflictor.items2 & HIP_IT_EMPATHY_SHIELDS) && (targ != attacker))
  147.       {
  148.       empathyused = 1;
  149.       damage = damage/2;
  150.       T_Damage (attacker,targ,targ,damage);
  151.       empathyused = 0;
  152.       }
  153. //MED
  154. // used by buttons and triggers to set activator for target firing
  155.     damage_attacker = attacker;
  156.  
  157. //MED
  158. // used to keep track of what hit us
  159.    damage_inflictor = inflictor;
  160. //hip
  161.  
  162. // save damage based on the target's armor level
  163.  
  164.     save = ceil(targ.armortype*damage);
  165.     if (save >= targ.armorvalue)
  166.     {
  167.         save = targ.armorvalue;
  168.         targ.armortype = 0;    // lost all armor
  169.         targ.items = targ.items - (targ.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3));
  170.     }
  171.     
  172.     targ.armorvalue = targ.armorvalue - save;
  173.     take = ceil(damage-save);
  174.  
  175. // add to the damage total for clients, which will be sent as a single
  176. // message at the end of the frame
  177. // FIXME: remove after combining shotgun blasts?
  178.     if (targ.flags & FL_CLIENT)
  179.     {
  180.         targ.dmg_take = targ.dmg_take + take;
  181.         targ.dmg_save = targ.dmg_save + save;
  182.         targ.dmg_inflictor = inflictor;
  183.     }
  184.  
  185. // figure momentum add
  186.     if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) )
  187.     {
  188.         dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5;
  189.         dir = normalize(dir);
  190.         targ.velocity = targ.velocity + dir*damage*8;
  191.     }
  192.  
  193. // check for godmode or invincibility
  194.     if (targ.flags & FL_GODMODE)
  195.         return;
  196.     if (targ.invincible_finished >= time)
  197.     {
  198.         if (self.invincible_sound < time)
  199.         {
  200.             sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
  201.             self.invincible_sound = time + 2;
  202.         }
  203.         return;
  204.     }
  205.  
  206. //hip
  207. //MED
  208.    if (targ.items2 & HIP_IT_EMPATHY_SHIELDS)
  209.     {
  210.       if (self.empathy_sound < time)
  211.         {
  212.          sound (targ, CHAN_ITEM, "hipitems/empathy2.wav", 1, ATTN_NORM);
  213.          self.empathy_sound = time + 0.5;
  214.         }
  215.     }
  216. //hip
  217.  
  218. // team play damage avoidance
  219. //ZOID 12-13-96: self.team doesn't work in QW.  Use keys
  220.     s = infokey(attacker, "bottomcolor");
  221.     attackerteam = stof(s);
  222.     s = infokey(targ, "bottomcolor");
  223.     targteam = stof(s);
  224.     if ( (teamplay == 1) && (targteam == attackerteam) )
  225.         return;
  226.         
  227. // do the damage
  228.     targ.health = targ.health - take;
  229.             
  230.     if (targ.health <= 0)
  231.     {
  232.         Killed (targ, attacker);
  233.         return;
  234.     }
  235.  
  236. // react to the damage
  237.     oldself = self;
  238.     self = targ;
  239.  
  240. /*SERVER
  241.     if ( (self.flags & FL_MONSTER) && attacker != world)
  242.     {
  243.     // get mad unless of the same class (except for soldiers)
  244.         if (self != attacker && attacker != self.enemy
  245. //hip
  246.  && (self.charmer!=attacker))
  247. //hip
  248.         {
  249.             if ( (self.classname != attacker.classname) 
  250.             || (self.classname == "monster_army" )
  251. //hip
  252.  || (self.classname == "monster_armagon" ) 
  253. //hip
  254. )
  255.             {
  256.                 if (self.enemy.classname == "player")
  257.                     self.oldenemy = self.enemy;
  258.                 self.enemy = attacker;
  259.                 FoundTarget ();
  260.             }
  261.         }
  262.     }
  263. */
  264.     if (self.th_pain)
  265.     {
  266.         self.th_pain (attacker, take);
  267.     }
  268.  
  269.     self = oldself;
  270. };
  271.  
  272. /*
  273. ============
  274. T_RadiusDamage
  275. ============
  276. */
  277. void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage =
  278. {
  279.     local    float     points;
  280.     local    entity    head;
  281.     local    vector    org;
  282.  
  283.     head = findradius(inflictor.origin, damage+40);
  284.     
  285.     while (head)
  286.     {
  287.         if (head != ignore)
  288.         {
  289.             if (head.takedamage)
  290.             {
  291.                 org = head.origin + (head.mins + head.maxs)*0.5;
  292.                 points = 0.5*vlen (inflictor.origin - org);
  293.                 if (points < 0)
  294.                     points = 0;
  295.                 points = damage - points;
  296.                 if (head == attacker)
  297.                     points = points * 0.5;
  298.                 if (points > 0)
  299.                 {
  300.                     if (CanDamage (head, inflictor))
  301.                     {    // shambler takes half damage from all explosions
  302.                         if (head.classname == "monster_shambler")                        
  303.                             T_Damage (head, inflictor, attacker, points*0.5);
  304.                         else
  305.                             T_Damage (head, inflictor, attacker, points);
  306.                     }
  307.                 }
  308.             }
  309.         }
  310.         head = head.chain;
  311.     }
  312. };
  313.  
  314. /*
  315. ============
  316. T_BeamDamage
  317. ============
  318. */
  319. void(entity attacker, float damage) T_BeamDamage =
  320. {
  321.     local    float     points;
  322.     local    entity    head;
  323.     
  324.     head = findradius(attacker.origin, damage+40);
  325.     
  326.     while (head)
  327.     {
  328.         if (head.takedamage)
  329.         {
  330.             points = 0.5*vlen (attacker.origin - head.origin);
  331.             if (points < 0)
  332.                 points = 0;
  333.             points = damage - points;
  334.             if (head == attacker)
  335.                 points = points * 0.5;
  336.             if (points > 0)
  337.             {
  338.                 if (CanDamage (head, attacker))
  339.                 {
  340.                     if (head.classname == "monster_shambler")                        
  341.                         T_Damage (head, attacker, attacker, points*0.5);
  342.                     else
  343.                         T_Damage (head, attacker, attacker, points);
  344.                 }
  345.             }
  346.         }
  347.         head = head.chain;
  348.     }
  349. };
  350.  
  351.